package serviceset1

import au.com.dius.pact.consumer.PactVerificationResult
import au.com.dius.pact.consumer.groovy.PactBuilder
import feign.Feign
import feign.gson.GsonDecoder
import feign.httpclient.ApacheHttpClient
import grails.gorm.transactions.Rollback
import grails.testing.mixin.integration.Integration
import org.grails.web.json.JSONObject
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.context.WebApplicationContext
import serviceset1.feign.ServiceSet2
import spock.lang.Specification

@Integration
@Rollback
class SampleApiControllerSpec extends Specification {

    @Autowired
    WebApplicationContext ctx

    def setup() {
        grails.util.GrailsWebMockUtil.bindMockWebRequest(ctx)
    }

    def cleanup() {
        org.springframework.web.context.request.RequestContextHolder.resetRequestAttributes()
    }

    void "test /sampleApi1"() {
        given:
        def dependency = "feign"
        def mockProvider = new PactBuilder() // Create a new PactBuilder
        mockProvider {
            serviceConsumer "serviceSet2"    // Define the service consumer by name
            hasPactWith "SERVICE-SET-2"   // Define the service provider that it has a pact with
            port 1234
            // The port number for the service. It is optional, leave it out to use a random one

            //given('there is a rest api') // defines a provider state. It is optional.
            uponReceiving('a request to GET result of /sampleApi2') // upon_receiving starts a new interaction
            withAttributes(method: 'get', path: '/sampleApi2', query: [dependency: dependency])
            // define the request, a GET request to '/sampleApi2'
            willRespondWith(                        // define the response we want returned
                    status: 200,
                    headers: ['Content-Type': 'application/json'],
                    body: [provider: "sampleApi2@serviceSet2", dependency: dependency]
            )
        }

        when:
        def result = mockProvider.runTest { mockServer ->
            def controller = new SampleApi1Controller()

            controller.serviceSet2 = Feign.builder()
                    .client(new ApacheHttpClient())
                    .decoder(new GsonDecoder())
                    .target(ServiceSet2.class, mockServer.url as String)

            controller.params.dependency = dependency
            controller.index()

            assert controller.response.status == 200
            JSONObject jsonResp = grails.converters.JSON.parse(controller.response.content as String)
            assert jsonResp.provider == "sampleApi1@serviceSet1"
        }

        then:
        result == PactVerificationResult.Ok.INSTANCE  // This means it is all good
    }
}
